package thread.synchroCode;

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.client.RestTemplate;

import java.util.Arrays;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

import static java.lang.Thread.sleep;

@Slf4j(topic = "c.TestCountDownLatch")
public class _13CountdownLatch {
  public static void main(String[] args) throws InterruptedException, ExecutionException {
    test2();
  }

  private static void test5() {
    CountDownLatch latch = new CountDownLatch(3);
    ExecutorService service = Executors.newFixedThreadPool(4);
    service.submit(() -> {
      log.debug("begin...");
      try {
        sleep(1);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
      latch.countDown();
      log.debug("end...{}", latch.getCount());
    });
    service.submit(() -> {
      log.debug("begin...");
      try {
        sleep((long) 1.5);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
      latch.countDown();
      log.debug("end...{}", latch.getCount());
    });
    service.submit(() -> {
      log.debug("begin...");
      try {
        sleep(2);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
      latch.countDown();
      log.debug("end...{}", latch.getCount());
    });
    service.submit(()->{
      try {
        log.debug("waiting...");
        latch.await();
        log.debug("wait end...");
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    });
  }

  private static void test4() throws InterruptedException {
    CountDownLatch latch = new CountDownLatch(3);

    new Thread(() -> {
      log.debug("begin...");
      try {
        sleep(1);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
      latch.countDown();
      log.debug("end...{}", latch.getCount());
    }).start();

    new Thread(() -> {
      log.debug("begin...");
      try {
        sleep(2);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
      latch.countDown();
      log.debug("end...{}", latch.getCount());
    }).start();

    new Thread(() -> {
      log.debug("begin...");
      try {
        sleep((long) 1.5);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
      latch.countDown();
      log.debug("end...{}", latch.getCount());
    }).start();

    log.debug("waiting...");
    latch.await();
    log.debug("wait end...");
  }

  private static void test3() throws InterruptedException, ExecutionException {
    RestTemplate restTemplate = new RestTemplate();
    log.debug("begin");
    ExecutorService service = Executors.newCachedThreadPool();
    CountDownLatch latch = new CountDownLatch(4);
    Future<Map<String,Object>> f1 = service.submit(() -> {
      Map<String, Object> response = restTemplate.getForObject("http://localhost:8080/order/{1}", Map.class, 1);
      return response;
    });
    Future<Map<String, Object>> f2 = service.submit(() -> {
      Map<String, Object> response1 = restTemplate.getForObject("http://localhost:8080/product/{1}", Map.class, 1);
      return response1;
    });
    Future<Map<String, Object>> f3 = service.submit(() -> {
      Map<String, Object> response1 = restTemplate.getForObject("http://localhost:8080/product/{1}", Map.class, 2);
      return response1;
    });
    Future<Map<String, Object>> f4 = service.submit(() -> {
      Map<String, Object> response3 = restTemplate.getForObject("http://localhost:8080/logistics/{1}", Map.class, 1);
      return response3;
    });

    System.out.println(f1.get());
    System.out.println(f2.get());
    System.out.println(f3.get());
    System.out.println(f4.get());
    log.debug("执行完毕");
    service.shutdown();
  }

  private static void test2() throws InterruptedException {
    AtomicInteger num = new AtomicInteger(0);
    ExecutorService service = Executors.newFixedThreadPool(10, (r) -> {
      return new Thread(r, "t" + num.getAndIncrement());
    });
    CountDownLatch latch = new CountDownLatch(10);
    String[] all = new String[10];
    Random r = new Random();
    for (int j = 0; j < 10; j++) {
      int x = j;
      service.submit(() -> {
        for (int i = 0; i <= 100; i++) {
          try {
            sleep(r.nextInt(100));
          } catch (InterruptedException e) {
          }
          all[x] = Thread.currentThread().getName() + "(" + (i + "%") + ")";
          System.out.print("\r" + Arrays.toString(all));
        }
        latch.countDown();
      });
    }
    latch.await();
    System.out.println("\n游戏开始...");
    service.shutdown();
  }
}
